import cv2
import time
from .image_processor import ImageProcessor
from .object_detector import ObjectDetector
from .semantic_analyzer import SemanticAnalyzer
from .visualizer import Visualizer

class BusinessApplication:
    """业务应用基类"""
    
    def __init__(self, name="通用应用"):
        """初始化业务应用
        
        Args:
            name: 应用名称
        """
        self.name = name
        self.is_running = False
        # 创建实例，在使用时才创建
        self.image_processor = ImageProcessor()
        self.detector = ObjectDetector()
        self.semantic_analyzer = SemanticAnalyzer()
        self.visualizer = Visualizer()
    
    def process_frame(self, frame):
        """处理单帧图像
        
        Args:
            frame: 输入图像
        
        Returns:
            处理后的图像
        """
        # 基本处理流程 - 不使用直方图均衡化，避免颜色失真
        preprocessed_frame = self.image_processor.preprocess_image(frame, use_equalize=False)
        detections, labels = self.detector.detect_objects(preprocessed_frame)
        
        if detections is not None and len(detections) > 0:
            description = self.semantic_analyzer.analyze_scene(preprocessed_frame, detections, self.detector.model.names)
            visualized_frame = self.visualizer.visualize_results(preprocessed_frame, detections, labels, description)
        else:
            visualized_frame = preprocessed_frame.copy()
            cv2.putText(
                visualized_frame,
                "No objects detected",
                (10, 30),
                cv2.FONT_HERSHEY_COMPLEX_SMALL,
                1,
                (0, 0, 255),
                2
            )
        
        return visualized_frame
    
    def start(self):
        """启动应用"""
        self.is_running = True
        print(f"{self.name}已启动")
    
    def stop(self):
        """停止应用"""
        self.is_running = False
        print(f"{self.name}已停止")

class SecurityMonitoringApp(BusinessApplication):
    """安防监控应用"""
    
    def __init__(self):
        """初始化安防监控应用"""
        super().__init__(name="安防监控应用")
        self.security_classes = ["person", "car", "truck", "motorcycle"]
        self.motion_detected = False
        self.prev_frame = None
        self.alarm_threshold = 5  # 连续检测到异常的帧数
        self.alarm_count = 0
    
    def process_frame(self, frame):
        """处理安防监控场景的单帧图像
        
        Args:
            frame: 输入图像
        
        Returns:
            处理后的图像
        """
        # 图像预处理 - 不使用直方图均衡化，避免颜色失真
        preprocessed_frame = self.image_processor.preprocess_image(frame, use_equalize=False)
        
        # 运动检测
        if self.prev_frame is not None:
            motion_mask = self.image_processor.detect_motion(self.prev_frame, preprocessed_frame)
            motion_pixels = cv2.countNonZero(motion_mask)
            self.motion_detected = motion_pixels > preprocessed_frame.shape[0] * preprocessed_frame.shape[1] * 0.01
        
        self.prev_frame = preprocessed_frame.copy()
        
        # 目标检测，只关注安防相关类别
        detections, labels = self.detector.detect_objects(preprocessed_frame)
        
        if detections is not None and len(detections) > 0:
            # 过滤安防相关类别
            security_detections = self.detector.filter_detections_by_class(detections, self.security_classes)
            
            # 更新标签
            security_labels = [
                f"{self.detector.model.names[class_id]} {confidence:.2f} ID:{tracker_id}"
                for class_id, confidence, tracker_id
                in zip(security_detections.class_id, security_detections.confidence, security_detections.tracker_id)
            ]
            
            # 语义分析
            description = self.semantic_analyzer.analyze_scene(preprocessed_frame, security_detections, self.detector.model.names)
            
            # 异常检测
            class_counts = self.detector.get_class_counts(security_detections)
            anomalies = self.semantic_analyzer.detect_anomalies(class_counts)
            
            if anomalies:
                self.alarm_count += 1
                if self.alarm_count >= self.alarm_threshold:
                    description += "⚠️ 检测到异常情况！\n"
                    for anomaly in anomalies:
                        description += f"- {anomaly['message']}\n"
            else:
                self.alarm_count = 0
            
            # 可视化
            visualized_frame = self.visualizer.visualize_results(preprocessed_frame, security_detections, security_labels, description)
        else:
            visualized_frame = preprocessed_frame.copy()
            cv2.putText(
                visualized_frame,
                "未检测到安防相关目标",
                (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX,
                1,
                (0, 0, 255),
                2
            )
        
        # 添加应用名称
        cv2.putText(
            visualized_frame,
            self.name,
            (10, visualized_frame.shape[0] - 20),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.7,
            (255, 255, 255),
            2
        )
        
        return visualized_frame

class TrafficMonitoringApp(BusinessApplication):
    """交通监控应用"""
    
    def __init__(self):
        """初始化交通监控应用"""
        super().__init__(name="交通监控应用")
        self.traffic_classes = ["car", "truck", "bus", "motorcycle", "bicycle"]
        self.vehicle_count = 0
        self.last_count_time = time.time()
        self.count_interval = 5  # 统计间隔（秒）
    
    def process_frame(self, frame):
        """处理交通监控场景的单帧图像
        
        Args:
            frame: 输入图像
        
        Returns:
            处理后的图像
        """
        # 图像预处理 - 不使用直方图均衡化，避免颜色失真
        preprocessed_frame = self.image_processor.preprocess_image(frame, use_equalize=False)
        
        # 目标检测，只关注交通相关类别
        detections, labels = self.detector.detect_objects(preprocessed_frame)
        
        if detections is not None and len(detections) > 0:
            # 过滤交通相关类别
            traffic_detections = self.detector.filter_detections_by_class(detections, self.traffic_classes)
            
            # 更新标签
            traffic_labels = [
                f"{self.detector.model.names[class_id]} {confidence:.2f} ID:{tracker_id}"
                for class_id, confidence, tracker_id
                in zip(traffic_detections.class_id, traffic_detections.confidence, traffic_detections.tracker_id)
            ]
            
            # 语义分析
            description = self.semantic_analyzer.analyze_scene(preprocessed_frame, traffic_detections, self.detector.model.names)
            
            # 交通流量统计
            current_time = time.time()
            if current_time - self.last_count_time >= self.count_interval:
                self.vehicle_count = len(traffic_detections)
                self.last_count_time = current_time
                
                # 交通状况判断
                if self.vehicle_count > 10:
                    description += "🚗 交通流量较大\n"
                elif self.vehicle_count > 5:
                    description += "🚗 交通流量中等\n"
                else:
                    description += "🚗 交通流量较小\n"
            
            # 可视化
            visualized_frame = self.visualizer.visualize_results(preprocessed_frame, traffic_detections, traffic_labels, description)
            
            # 创建热力图显示车辆密度
            heatmap_frame = self.visualizer.create_heatmap(preprocessed_frame, traffic_detections)
            # 将热力图添加到可视化结果旁边
            combined_frame = cv2.hconcat([visualized_frame, heatmap_frame])
            
            return combined_frame
        else:
            visualized_frame = preprocessed_frame.copy()
            cv2.putText(
                visualized_frame,
                "未检测到交通相关目标",
                (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX,
                1,
                (0, 0, 255),
                2
            )
        
        # 添加应用名称
        cv2.putText(
            visualized_frame,
            self.name,
            (10, visualized_frame.shape[0] - 20),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.7,
            (255, 255, 255),
            2
        )
        
        return visualized_frame

class IndustrialInspectionApp(BusinessApplication):
    """工业质检应用"""
    
    def __init__(self):
        """初始化工业质检应用"""
        super().__init__(name="工业质检应用")
        self.inspection_classes = ["bottle", "cup", "cell phone", "laptop"]  # 示例工业部件类别
        self.defect_threshold = 0.1  # 缺陷判定阈值
    
    def process_frame(self, frame):
        """处理工业质检场景的单帧图像
        
        Args:
            frame: 输入图像
        
        Returns:
            处理后的图像
        """
        # 图像预处理，增强对比度以更好地检测缺陷
        preprocessed_frame = self.image_processor.preprocess_image(frame, use_equalize=True)  # 工业场景下可以使用均衡化
        enhanced_frame = self.image_processor.adjust_brightness_contrast(preprocessed_frame, contrast=20)
        
        # 目标检测
        detections, labels = self.detector.detect_objects(enhanced_frame)
        
        if detections is not None and len(detections) > 0:
            # 过滤检测结果
            inspection_detections = self.detector.filter_detections_by_class(detections, self.inspection_classes)
            
            # 更新标签
            inspection_labels = [
                f"{self.detector.model.names[class_id]} {confidence:.2f} ID:{tracker_id}"
                for class_id, confidence, tracker_id
                in zip(inspection_detections.class_id, inspection_detections.confidence, inspection_detections.tracker_id)
            ]
            
            # 语义分析
            description = self.semantic_analyzer.analyze_scene(enhanced_frame, inspection_detections, self.detector.model.names)
            
            # 简单的缺陷检测（基于置信度）
            defect_count = 0
            for confidence in inspection_detections.confidence:
                if confidence < self.defect_threshold:
                    defect_count += 1
            
            if defect_count > 0:
                description += f"🔍 发现{defect_count}个可能存在缺陷的部件\n"
            else:
                description += "✅ 未发现明显缺陷\n"
            
            # 可视化
            visualized_frame = self.visualizer.visualize_results(enhanced_frame, inspection_detections, inspection_labels, description)
        else:
            visualized_frame = enhanced_frame.copy()
            cv2.putText(
                visualized_frame,
                "未检测到质检目标",
                (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX,
                1,
                (0, 0, 255),
                2
            )
        
        # 添加应用名称
        cv2.putText(
            visualized_frame,
            self.name,
            (10, visualized_frame.shape[0] - 20),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.7,
            (255, 255, 255),
            2
        )
        
        return visualized_frame

# 创建各业务应用的实例
def create_application(app_type):
    """创建指定类型的业务应用
    
    Args:
        app_type: 应用类型
    
    Returns:
        业务应用实例
    """
    if app_type == "security":
        return SecurityMonitoringApp()
    elif app_type == "traffic":
        return TrafficMonitoringApp()
    elif app_type == "industrial":
        return IndustrialInspectionApp()
    else:
        return BusinessApplication()